local anims = {
    "yawn", "dozy", "sleep_loop", -- 催眠，冰冻，粘痰等
    "powerdown", -- 大力士变小
    "buck", "mount", "dismount", "heavy_mount", -- 骑牛相关（来自：圈外人）
    "powerup", -- 大力士变大动画, 不推荐解除这个, 影响健身
    -- "useitem_lag","useitem_pst", -- 旺达和蜘蛛人的后摇，不推荐
    "jumpportal_out" -- 旺达降落解控
    , "knockback_high", "buck_pst", -- 恶梦猪人
    "empty", -- 墨荒吃人辣
    "pickaxe_recoil", -- 敲柱子
    -- "book",                                                             -- 老麦读书
}
local task
local FS = GLOBAL.TheSim:GetTickTime()
local timedelay = 0.25
local WOWData = "WalkOnTheWater"
local p_util = require "libs/playerutil"

local function checkAnims(anims)
    local Anim = GLOBAL.ThePlayer and GLOBAL.ThePlayer.AnimState
    if Anim then
        for _, anim in pairs(anims) do
            if Anim:IsCurrentAnimation(anim) then
                return anim
            end
        end
    end
    return false
end



local function TryCraft(check)
    for recname, rec in pairs(GLOBAL.AllRecipes) do
        if GLOBAL.IsRecipeValid(recname) and rec.placer == nil and rec.sg_state ==
            nil and GLOBAL.ThePlayer.replica.builder:KnowsRecipe(recname) and
            GLOBAL.ThePlayer.replica.builder:CanBuild(recname) then
            if check then return true end
            GLOBAL.SendRPCToServer(GLOBAL.RPC.MakeRecipeFromMenu, rec.rpc_id)
            return rec
        end
    end
end

GLOBAL.MOD_ShroomCake.Func.TryCraft = TryCraft

local function Atest(addtimedelay)
    if not TryCraft(true) then return end
    addtimedelay = addtimedelay or 0
    local c = GLOBAL.ThePlayer and GLOBAL.ThePlayer.components.playercontroller
    if not c then return end
    local movementprediction = GLOBAL.Profile and GLOBAL.Profile:GetMovementPredictionEnabled()
    if movementprediction then GLOBAL.ThePlayer:EnableMovementPrediction(false) end
    TryCraft()
    

    local function runAndStop()
        GLOBAL.ThePlayer:DoTaskInTime(addtimedelay, function()
            if not table.contains({"build_pre", "build_loop", "jump"}, GetAnim(GLOBAL.ThePlayer))then
                return
            end
            if GLOBAL.TheWorld.ismastersim then
                c:DoAction(GLOBAL.BufferedAction(GLOBAL.ThePlayer, nil, GLOBAL.ACTIONS.WALKTO, nil, GLOBAL.Vector3(0, 0, 0)))
            else
                GLOBAL.SendRPCToServer(GLOBAL.RPC.DirectWalking, 0, 0)
            end
            GLOBAL.ThePlayer:DoTaskInTime(0, function() 
                if c then
                    if GLOBAL.TheWorld.ismastersim then
                        local pos = GLOBAL.ThePlayer and GLOBAL.ThePlayer.Transform and GLOBAL.ThePlayer:GetPosition()
                        c:DoAction(GLOBAL.BufferedAction(GLOBAL.ThePlayer, nil, GLOBAL.ACTIONS.WALKTO, nil, pos or GLOBAL.Vector3(0, 0, 0)))
                    else
                        GLOBAL.SendRPCToServer(GLOBAL.RPC.StopWalking)
                    end
                    if movementprediction and GLOBAL.ThePlayer then
                        GLOBAL.ThePlayer:EnableMovementPrediction(true)
                    end
                end       
            end)
        end)
        TIP("自动解控", "green", "尝试解控", "head")
    end
    runAndStop()
    GLOBAL.ThePlayer:DoTaskInTime(0, runAndStop)
    GLOBAL.ThePlayer:DoTaskInTime(0.05, runAndStop)
    GLOBAL.ThePlayer:DoTaskInTime(0.1, runAndStop)
    GLOBAL.ThePlayer:DoTaskInTime(0.15, runAndStop)
    GLOBAL.ThePlayer:DoTaskInTime(0.2, runAndStop)
    GLOBAL.ThePlayer:DoTaskInTime(0.25, runAndStop)
    GLOBAL.ThePlayer:DoTaskInTime(0.3, runAndStop)
end

local function WowAutoTask()
    local a
    task = GLOBAL.ThePlayer:DoPeriodicTask(timedelay, function()
        a = checkAnims(anims)
        if a then
            if a == "powerup" then
                local hand = GetEquippedItemFrom("hands")
                if hand and hand:HasTag("dumbbell") then
                else
                    Atest()
                end
            else
                Atest()  
            end
        end
    end)
end

local lasttime = 0
GLOBAL.MOD_ShroomCake.Setting.wormholecheck = LoadModData(WOWData) or false
local function func_fade(pc)
    if not GLOBAL.MOD_ShroomCake.Setting.wormholecheck then return end
    if pc.currentwereness and pc.currentwereness:value() ~= 0 then
        return
    end
    local now = GLOBAL.os.clock()
    local cal = now - lasttime
    -- 这个锁用于服务器发送了两次此事件，只处理第一次
    if cal > 3.5 or cal < 2.5 then
        Atest()
    end
    lasttime = now
end
AddPlayerActivatedFunc(function(player)
    if GLOBAL.MOD_ShroomCake.Setting.wormholecheck then
        WowAutoTask()
    end
end)

AddPrefabPostInit("player_classified", function(pc)
    pc:DoTaskInTime(1, function()
        if pc.event_listeners and pc.event_listeners.playerfadedirty then
            pc.event_listeners.playerfadedirty[pc] = nil
        end
        if pc.event_listening and pc.event_listening.playerfadedirty then
            pc.event_listening.playerfadedirty[pc] = nil
        end
        p_util:SetBindEvent("playerfadedirty", func_fade)
    end)
end)

local oldSendRPCToServer = GLOBAL.SendRPCToServer
function GLOBAL.SendRPCToServer(rpc, actcode, target, a, b, ...)
    -- 右键使用 和 快捷键使用
    if actcode == GLOBAL.ACTIONS.CAST_POCKETWATCH.code 
        and (rpc == GLOBAL.RPC.UseItemFromInvTile or rpc ==
        GLOBAL.RPC.ControllerUseItemOnSelfFromInvTile)
        and type(target) == "table" and
        (target.prefab == "pocketwatch_recall" or target.prefab ==
            "pocketwatch_warp") 
    or  ( actcode == GLOBAL.ACTIONS.CAST_POCKETWATCH.code
        and rpc == GLOBAL.RPC.LeftClick 
        and b == GLOBAL.ThePlayer) 
    -- 骑牛搬运雕像无法适配：原因：不晓得哪个功能接管了右键发送rpc
    -- or (type(b)=="table" and b:HasTag("heavy") 
    --     and rpc == GLOBAL.RPC.RightClick
    --     and actcode == GLOBAL.ACTIONS.PICKUP.code
    --     and GLOBAL.ThePlayer and GLOBAL.ThePlayer.replica.rider
    --     and GLOBAL.ThePlayer.replica.rider.classified.ridermount:value())
    then
        if GLOBAL.MOD_ShroomCake.Setting.wormholecheck then
            GLOBAL.MOD_ShroomCake.Setting.wormholecheck = false
            GLOBAL.ThePlayer:DoTaskInTime(1.5,
                                        function()
                GLOBAL.MOD_ShroomCake.Setting.wormholecheck = true
            end)
        end
    -- else
    --     local ri = rpc
    --     for k,v in pairs(GLOBAL.RPC)do 
    --         if rpc == v then 
    --             ri = k 
    --         end 
    --     end 
    --     local ai = actcode
    --     for k,v in pairs(GLOBAL.ACTIONS)do 
    --         if v.code == actcode then 
    --             ai = k 
    --         end 
    --     end 
    --     print(ri, ai, b)
    end
    oldSendRPCToServer(rpc, actcode, target, a, b, ...)
end

local function fn()
    if not InGame() then return end

    if task then
        task:Cancel()
        task = nil
        GLOBAL.MOD_ShroomCake.Setting.wormholecheck = false
        TIP("解除控制", nil, GLOBAL.MOD_ShroomCake.Setting.wormholecheck)
        SaveModData(WOWData, false)
        return
    end

    if not TryCraft(true) then
        TIP("功能错误", "red", "没有能搓的东西,请准备点材料")
        SaveModData(WOWData, false)
        return
    else
        GLOBAL.MOD_ShroomCake.Setting.wormholecheck = true
        TIP("功能开启", "green", "解控已就绪")
        SaveModData(WOWData, true)
    end

    WowAutoTask()
end

if GetModConfigData("sw_wow") == "biubiu" then
    DEAR_BTNS:AddDearBtn(GLOBAL.GetInventoryItemAtlas("tophat_witch_pyre.tex"),
                         "tophat_witch_pyre.tex", "解除控制",
                         "卡海的残党，新时代没有承载我的船",
                         false, fn)
end

AddBindBtn("sw_wow", fn)

